package com.xkh.common.util;

import com.xkh.common.common.constant.ConstRedis;
import com.xkh.common.model.dto.NearbyPositionDTO;
import com.xkh.common.model.dto.PositionDTO;
import com.xkh.common.model.vo.UserPositionVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtils {

    private static RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    public void setRedisTemplate(RedisTemplate<Object, Object> redisTemplate) {
        RedisUtils.redisTemplate = redisTemplate;
    }

    /**
     * 添加 Hash 键值对
     * TimeUnit.SECONDS //秒
     */
    public void putHash(String key, Object hashKey, Object value, long dayTime) {
        redisTemplate.opsForHash().put(key, hashKey, value);
        expire(key, dayTime, TimeUnit.SECONDS);
    }

    public void putHash(String key, Object hashKey, Object value) {
        redisTemplate.opsForHash().put(key, hashKey, value);
    }

    public boolean putGeo(PositionDTO positionDTO) {
        redisTemplate.opsForGeo().remove(ConstRedis.NEARBY_POSITION,positionDTO.getUserId());
        Long flag = redisTemplate.opsForGeo().add(ConstRedis.NEARBY_POSITION, new RedisGeoCommands.GeoLocation<>(
                positionDTO.getUserId(),
                new Point(positionDTO.getLongitude(), positionDTO.getLatitude()))
        );
        return flag != null && flag > 0;
    }

    public List<Point> getGeo(Long userId) {
        return redisTemplate.opsForGeo().position(ConstRedis.NEARBY_POSITION,userId);
    }

    /**
     *  includeCoordinates(返回经纬度) 与 includeDistance(返回距离) 只能同时存在一个
     */
    public GeoResults<RedisGeoCommands.GeoLocation<Object>> getGeoCircle(NearbyPositionDTO nearbyPositionDTO) {
        return redisTemplate.opsForGeo().radius(ConstRedis.NEARBY_POSITION,
                new Circle(new Point(nearbyPositionDTO.getLongitude(), nearbyPositionDTO.getLatitude()),
                        new Distance(nearbyPositionDTO.getDistance(), Metrics.KILOMETERS)),
                RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().sortAscending());
    }

    public Object getHash(String key, Object hashKey) {
        return redisTemplate.opsForHash().get(key, hashKey);
    }


    public Boolean hashKey(String key,Object hashKey){
        return redisTemplate.opsForHash().hasKey(key,hashKey);
    }

    public void expire(String key, long time, TimeUnit type) {
        redisTemplate.boundValueOps(key).expire(time, type);
    }
}
